<template>
  <div class="chart" :id="cid" />
</template>
<script>
import * as echarts from "echarts";
export default {
  data() {
    return {};
  },
  props: {
    // 图表ID
    cid: {
      type: String,
      default: "",
      required: true,
    },
    // 图表数据
    data: {
      type: Array,
      default: () => [],
    },
    // 图表类型
    type: {
      type: [String, Array],
      default: "line",
    },
    // 柱状图显示标签
    barLabel: {
      type: [Boolean, Array],
      default: false,
    },
    // 柱状图宽度
    barWidth: {
      type: String,
      default: "20%",
    },
    // 柱状图标签位置 top / left / right / bottom / inside / insideLeft / insideRight / insideTop / insideBottom / insideTopLeft / insideBottomLeft / insideTopRight / insideBottomRight
    barLabelPos: {
      type: String,
      default: "top",
    },
    // 柱状图标签颜色
    barLabelColor: {
      type: String,
      default: "#fff",
    },
    // 柱状图标签大小
    barLabelSize: {
      type: Number,
      default: 12,
    },
    // 是否堆叠
    barStack: {
      type: Boolean,
      default: false,
    },
    // 平滑曲线
    smooth: {
      type: Boolean,
      default: false,
    },
    // X轴数据
    xAxis: {
      type: Array,
      default: () => [],
    },
    // 显示X轴上分割线
    xLine: {
      type: Boolean,
      default: false,
    },
    // X轴上分割线颜色
    xLineColor: {
      type: String,
      default: "#5a718b",
    },
    // 显示X轴上标签
    xLabel: {
      type: Boolean,
      default: true,
    },
    // X轴上标签大小
    xLabelSize: {
      type: [String, Number],
      default: 12,
    },
    // X轴上标签颜色
    xLabelColor: {
      type: String,
      default: "#fff",
    },
    // 显示X轴上刻度
    xTick: {
      type: Boolean,
      default: false,
    },
    // 显示Y轴上分割线
    yLine: {
      type: Boolean,
      default: true,
    },
    // Y轴上分割线颜色
    yLineColor: {
      type: String,
      default: "#5a718b",
    },
    // 显示Y轴上标签
    yLabel: {
      type: Boolean,
      default: true,
    },
    // 显示Y轴上刻度
    yTick: {
      type: Boolean,
      default: false,
    },
    // Y轴标签显示在图表内部
    yLabelInside: {
      type: Boolean,
      default: false,
    },
    // Y轴上标签大小
    yLabelSize: {
      type: [String, Number],
      default: 12,
    },
    // Y轴上标签颜色
    yLabelColor: {
      type: String,
      default: "#fff",
    },
    // Y轴上标签偏移
    yOffset: {
      type: [String, Number],
      default: 0,
    },
    // // 目标线颜色
    // markLineColor: {
    //   type: String,
    //   default: "#95f204",
    // },
    // // 目标线宽度
    markLineWidth: {
      type: [String, Number],
      default: 1,
    },
    // // 显示目标线文字
    // markLabel: {
    //   type: Boolean,
    //   default: false,
    // },
    // // 目标线文字位置
    // markLabelPos: {
    //   type: String,
    //   default: "start",
    // },
    // // 目标线文字大小
    // markLabelSize: {
    //   type: [String, Number],
    //   default: 12,
    // },
    // // 目标线文字颜色
    // markLabelColor: {
    //   type: String,
    //   default: "#fff",
    // },
    // 单位
    unit: {
      type: String,
      default: "",
    },
    // 单位距离
    nameGap: {
      type: [String, Number],
      default: 15,
    },
    // 单位位置
    nameLocation: {
      type: String,
      default: "end",
    },
    // 单位大小
    unitSize: {
      type: [String, Number],
      default: 10,
    },
    lineWidth: {
      type: [String, Number],
      default: 2,
    },
    lineType: {
      type: String,
      default: "dotted",
    },
    // 单位颜色
    unitColor: {
      type: String,
      default: "#DFEFFF",
    },
    // 显示图例
    legend: {
      type: Boolean,
      default: true,
    },
    // 图例文本颜色
    legColor: {
      type: String,
      default: "#fff",
    },
    // 图例图标形状
    // 'circle','rect', 'roundRect', 'triangle', 'diamond', 'pin', 'arrow', 'none'
    legIcon: {
      type: String,
      default: "rect",
    },
    // 图例宽度
    legWidth: {
      type: [String, Number],
      default: 400,
    },
    // 图例图标大小
    legIconSize: {
      type: [String, Number],
      default: 10,
    },
    // 图例距离顶部的距离
    legTop: {
      type: [String, Number, null],
      default: null,
    },
    // 图例距离左边的距离
    legLeft: {
      type: [String, Number, null],
      default: null,
    },
    // 图例距离右边的距离
    legRight: {
      type: [String, Number, null],
      default: null,
    },
    // 图例距离底部的距离
    legBottom: {
      type: [String, Number, null],
      default: null,
    },
    // 显示提示框
    tooltip: {
      type: Boolean,
      default: true,
    },
    // 图表距离顶部的距离
    gridTop: {
      type: String,
      default: "16%",
    },
    // 图表距离左边的距离
    gridLeft: {
      type: String,
      default: "3%",
    },
    // 图表距离右边的距离
    gridRight: {
      type: String,
      default: "4%",
    },
    // 图表距离底部的距离
    gridBottom: {
      type: String,
      default: "2%",
    },
    // 颜色 若需要渐变色，将字符串颜色写成数组。如：[['#FFFE54', '#001DF5']]
    colors: {
      type: Array,
      default: () => ["#F928F6", "#157DFA"],
    },
    dotColors: {
      type: String,
      default: "#fff",
    },
    areaColor: {
      type: Array,
      default: () => ["", ""],
    },
    // 上限颜色
    limitColors: {
      type: Array,
      default: () => [],
    },
    // 显示背景色
    showBackground: {
      type: Boolean,
      default: false,
    },
    // 方向 水平horizontal 垂直vertical
    orient: {
      type: String,
      default: "vertical",
    },
  },
  watch: {
    data: {
      immediate: true,
      handler() {
        this.$nextTick(() => {
          this.initChart();
        })
      },
    },
  },
  methods: {
    // 初始化图表
    initChart() {
      let domid = document.getElementById(this.cid);
      if (domid?.hasAttribute("_echarts_instance_"))
        domid.removeAttribute("_echarts_instance_");
      let myChart = this.$echarts.init(domid);
      let legData = [];
      let series = [];
      this.data.forEach((item, index) => {
        let t = "line";
        if (typeof this.type === "string") {
          t = this.type;
        } else {
          t =
            this.type.length - 1 < index
              ? this.type[this.type.length - 1]
              : this.type[index];
        }
        legData.push({
          name: item.name,
          itemStyle: {
            opacity: t === "line" ? 0 : 1,
          },
        });
        let itemObj = {
          data: item.data,
          type: t,
          smooth: this.smooth,
          name: item.name,
          symbol:
            typeof this.type === "string"
              ? this.legIcon
              : t === "line"
              ? "diamond"
              : this.legIcon,
        };
        if (
          this.type == "bar" ||
          (typeof this.type !== "string" && this.type.includes("bar"))
        ) {
          let labelShow =
            typeof this.barLabel === "boolean"
              ? this.barLabel
              : this.barLabel[index];
          itemObj = {
            ...itemObj,
            barGap: "0%",
            barWidth: this.barWidth,
            stack: this.barStack ? "stack" : null,
            showBackground: this.showBackground,
            backgroundStyle: {
              color: {
                type: "linear",
                x: 0,
                y: 0,
                x2: 1,
                y2: 1,
                colorStops: [
                  { offset: 0, color: "#282c37" },
                  { offset: 1, color: "#1c202b" },
                ],
              },
            },

            itemStyle: {
              // normal: {
              //   lineStyle: (e) => {
              //     type: this.type == "line" ? this.lineType : "";
              //     width: this.type == "line" ? this.lineWidth : "2";
              //   },
              // },
              color: (e) => {
                if (typeof this.colors[0] == "string") {
                  return this.colors[index];
                }
                let colorItem = this.colors[index];
                if (this.limitColors.length > 0) {
                  if (
                    index === 0 &&
                    Number(item.data[e.dataIndex]) >= Number(this.data[1].data[e.dataIndex])
                  ) {
                    colorItem = this.limitColors;
                  }
                }
                return new echarts.graphic.LinearGradient(
                  this.orient === 'horizontal' ? 1 : 0,
                  0,
                  0,
                  this.orient === 'horizontal' ? 0 : 1,
                  [
                    { offset: 0, color: colorItem[0] },
                    { offset: 1, color: colorItem[1] },
                  ],
                  false
                );
              },
            },
            // markLine: {
            //   symbol: ["none", "none"],
            //   data: [{ type: "min", yAxis: 86 }],
            //   label: {
            //     show: this.markLabel,
            //     position: this.markLabelPos,
            //     color: this.markLabelColor,
            //     fontSize: this.markLabelSize,
            //   },
            //   lineStyle: {
            //     color: this.markLineColor,
            //     width: this.markLineWidth,
            //     type: "solid",
            //   },
            // },
            label: {
              show: labelShow,
              position: this.barLabelPos,
              fontSize: this.barLabelSize,
              formatter: "{c}",
              color: this.barLabelColor,
            },
          };
        }
        if (item.area) {
          itemObj.areaStyle = {
            opacity: 0.2,
            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
              { offset: 0, color: this.areaColor[0] },
              { offset: 1, color: this.areaColor[1] },
            ]),
          };
        }
        if (item.showSymbol) {
          itemObj = {
            ...itemObj,
            type: "line",
            symbol: "circle",
            showSymbol: item.showSymbol, //是否默认展示圆点
            symbolSize: 11,
            itemStyle: {
              normal: {
                borderColor: this.dotColors,
                borderWidth: 3,
              },
            },
          };
        }
        series.push(itemObj);
      });
      let color = null;
      if (typeof this.colors[0] == "string") {
        color = this.colors;
      } else {
        color = this.colors[0];
        let list = [];
        this.colors.forEach((i) => {
          list.push({
            type: "linear",
            x: 0,
            y: 0,
            x2: 0,
            y2: 1,
            colorStops: [
              { offset: 0, color: i[0] },
              { offset: 1, color: i[1] },
            ],
            global: false,
          });
        });
        color = list;
      }
      let option = {
        color: color,
        grid: {
          top: this.gridTop,
          left: this.gridLeft,
          right: this.gridRight,
          bottom: this.gridBottom,
          containLabel: true,
        },
        tooltip: {
          show: this.tooltip,
          trigger: "axis",
          axisPointer: {
            type: "line",
          },
        },
        legend: {
          show: this.legend,
          // icon: this.legIcon,
          width: this.legWidth,
          itemWidth: this.legIconSize,
          itemHeight: this.legIconSize,
          data: legData,
          right: this.legRight,
          top: this.legTop,
          left: this.legLeft,
          bottom: this.legBottom,
          textStyle: { color: this.legColor },
        },
        xAxis: {
          type: this.orient === 'horizontal' ? "value" : "category",
          data: this.xAxis,
          axisTick: {
            show: this.xTick,
            alignWithLabel: true,
          },
          axisLine: {
            show: this.xLine,
            lineStyle: { color: this.xLineColor },
          },
          splitLine: {
            show: this.xLine,
            lineStyle: {
              color: [this.xLineColor],
              width: 1,
              type: "dashed",
            },
          },
          axisLabel: {
            show: this.xLabel,
            textStyle: {
              color: this.xLabelColor,
              fontSize: this.xLabelSize,
            },
          },
        },
        yAxis: {
          show: this.data.length > 0,
          type: this.orient === 'horizontal' ? "category" : "value",
          name: this.unit,
          data: this.xAxis,
          nameGap: this.nameGap,
          offset: this.yOffset,
          nameLocation: this.nameLocation,
          nameTextStyle: {
            fontSize: this.unitSize,
            color: this.unitColor,
          },
          axisTick: {
            show: this.yTick,
            alignWithLabel: true,
          },
          splitLine: {
            show: this.yLine,
            lineStyle: {
              color: [this.yLineColor],
              width: 1,
              type: "dashed",
            },
          },
          axisLabel: {
            show: this.yLabel,
            inside: this.yLabelInside,
            textStyle: {
              fontSize: this.yLabelSize,
              color: this.yLabelColor,
            },
          },
        },
        series: series,
      };
      myChart.setOption(option, true, true);

      myChart.on("click", (params) => {
        this.$emit("click", params);
      });
      window.addEventListener("resize", () => {
        myChart.resize();
      });
    },
  },
};
</script>
<style lang="scss" scoped>
.chart {
  width: 100%;
  height: 100%;
}
</style>
